/**
 * Copyright 2006 Brad Reynolds
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.leeloo.databinding.internal.ui;

import java.util.Arrays;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.leeloo.core.Tag;
import org.leeloo.core.Tags;
import org.leeloo.databinding.ui.test.support.PluginTestCase;
import org.leeloo.databinding.ui.test.support.SWTNavigator;

public class TagSelectionDialogTest extends PluginTestCase {
    private Shell shell;
    private Tag[] tags;
    private TagSelectionDialog dialog;
    private Table table;
    
    protected void setUp() throws Exception {
        shell = new Shell();
        tags = new Tag[] {new Tag(Tags.ID, "1"), new Tag(Tags.ID, "2")};
        dialog = new TagSelectionDialog(shell, tags, null);
        dialog.setBlockOnOpen(false);
        dialog.open();
        
        table = getTable(dialog);
    }
    
    protected void tearDown() throws Exception {
        shell.dispose();
    }
    
    public void testControlCreation() throws Exception {
        TagSelectionDialog dialog = new TagSelectionDialog(shell, null, null);
        dialog.setBlockOnOpen(false);
        dialog.open();
        
        Control[] controls = new SWTNavigator(dialog.getShell()).getDescendantsByType(Table.class);
        assertEquals(1, controls.length);
        assertTrue(controls[0] instanceof Table);
        
        //Parent of the table is the Composite created in createDialog().
        Composite dialogArea = controls[0].getParent();
        
        controls = new SWTNavigator(dialogArea).getDescendantsByType(Button.class);
        assertEquals(2, controls.length);
    }
    
    public void testSetItems() throws Exception {
        assertEquals(2, table.getItemCount());
        assertTrue(table.getItem(0).getData() == tags[0]);
        assertTrue(table.getItem(1).getData() == tags[1]);
    }
    
    public void testSetSelection() throws Exception {
        Tag[] selection = new Tag[] {tags[0]};
        TagSelectionDialog dialog = new TagSelectionDialog(shell, tags, selection);
        dialog.setBlockOnOpen(false);
        dialog.open();

        Table table = getTable(dialog);
        assertTrue(table.getItem(0).getChecked());
    }
    
    public void testGetSelection() throws Exception {
        Tag[] selection = dialog.getSelection();
        assertNotNull(selection);
        assertEquals(0, selection.length);
        
        table.getItem(1).setChecked(true);
        Event event = new Event();
        event.item = table.getItem(1);
        event.detail = SWT.CHECK;
        table.notifyListeners(SWT.Selection, event);
        dialog.close();
        
        selection = dialog.getSelection();
        assertNotNull(selection);
        assertEquals(1, selection.length);
    }
    
    public void testGetItems() throws Exception {
        Tag[] tags = dialog.getTags();
        assertNotNull(tags);
        assertEquals(2, tags.length);
    }
    
    public void testAddItem() throws Exception {
        String display = "b:c";
        dialog.add(Tag.fromDisplay(display));
        
        assertEquals(display, ((Tag) table.getItem(2).getData()).getDisplay());
        assertTrue(table.getItem(2).getChecked());
    }
    
    public void testRemoveItem() throws Exception {
        checkItem(table, 1, true);
        
        Tag tag = tags[1];
        dialog.remove(tag);
        
        List items = Arrays.asList(dialog.getTags());
        assertFalse(items.contains(tag));
        
        List selection = Arrays.asList(dialog.getSelection());
        assertFalse(selection.contains(tag));
    }
    
    public void testEnableRemove() throws Exception {
        Control[] buttons = new SWTNavigator(table.getParent()).getDescendantsByType(Button.class);
        Button remove = (Button) buttons[1];
        assertEquals("Remove", remove.getText()); //$NON-NLS-1$
        assertFalse(remove.isEnabled());
        
        selectItem(table, 0);
        assertTrue(remove.isEnabled());
    }
    
    private Table getTable(TagSelectionDialog dialog) {
        Control[] controls = new SWTNavigator(dialog.getShell()).getDescendantsByType(Table.class);
        return (Table) controls[0];
    }
    
    private static void checkItem(Table table, int index, boolean check) {
        table.getItem(index).setChecked(check);
        Event event = new Event();
        event.item = table.getItem(index);
        event.detail = SWT.CHECK;
        table.notifyListeners(SWT.Selection, event);
    }
    
    private static void selectItem(Table table, int index) {
        table.setSelection(index);
        Event event = new Event();
        event.item = table.getItem(index); 
        table.notifyListeners(SWT.Selection, event);
    }
}
